# -*- coding: UTF-8 -*-

import re
from datetime import datetime
import sys
from sqlalchemy import and_, func, or_
from typing import Dict, List, Any, Generator

from sqlalchemy import Boolean, Column, DateTime, Integer, String, Index, Table, ForeignKey, text, JSON, TEXT, FLOAT
from sqlalchemy.orm import Session, relationship
from common.database import Base
from common.database import SessionMixin
from common.utils import is_empty
from core.logger import logger

__all__ = ['QosServiceInfo']


class QosServiceInfo(Base, SessionMixin):
    '''
    应用服务的信息
    '''
    __tablename__ = "qos_service_info"
    name = Column(String(256), nullable=False, index=True, comment='服务名称')
    # true/false 使能状态
    state = Column(Boolean, default=text('True'), nullable=False, comment='服务状态')
    # java or node or python or h5
    type = Column(String(128), nullable=False, index=True, comment='服务类型')
    # 服务器部署 or 容器部署
    classes = Column(String(128), nullable=False, index=True, comment='部署归类')
    department = Column(String(128), nullable=False, index=True, comment='所属部门')
    number = Column(Integer, nullable=False, default=0, comment='服务数量')
    cpu_request = Column(FLOAT, nullable=False, default=0, comment='cpu最低配额')
    cpu_limit = Column(FLOAT, nullable=False, default=0, comment='cpu最高配额')
    mem_request = Column(FLOAT, nullable=False, default=0, comment='内存最低配额')
    mem_limit = Column(FLOAT, nullable=False, default=0, comment='内存最高配额')
    port = Column(Integer, nullable=False, default=0, comment='服务端口')
    deploy_nodes = Column(JSON, nullable=False, default=[], comment='部署的节点名称列表')
    update_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
    comment = Column(String(256), nullable=True, comment='数据说明')

    __table_args__ = (
        Index('idx_qos_service_info_name', 'name', unique=True),
        {
            'mysql_engine': 'innodb',
            'mysql_charset': 'utf8mb4',
            'mysql_collate': 'utf8mb4_unicode_ci',
            'extend_existing': True,
            'mysql_row_format': 'dynamic'
        }
    )

    def __repr__(self):
        return f"<qos_service_info='{self.name}>"

    def object_to_dict(self, db: Session):
        result = {
            key: getattr(self, key)
            for key in self.__mapper__.c.keys()
        }
        return result

    # 删除所有的容器服务
    @classmethod
    def delete_by_container(cls, db: Session):
        db.query(cls).filter(
            cls.classes.in_(["k8s_statefulset", "k8s_deployment"])
        ).delete()
        db.commit()

    # 获取所有的容器服务
    @classmethod
    def get_by_container(cls, db: Session):
        object_info = db.query(cls).filter(
            cls.classes.in_(["k8s_statefulset", "k8s_deployment"])
        ).to_dict()

        return object_info
    
    # 获取所有在线的容器服务
    @classmethod
    def get_by_container_state(cls, db: Session):
        object_info = db.query(cls).filter(
            cls.state,
            cls.classes.in_(["k8s_statefulset", "k8s_deployment"])
        ).to_dict()

        return object_info

    # 获取所有在线服务
    @classmethod
    def get_all_by_state(cls, db: Session):
        object_info = db.query(cls).filter(
            cls.state
        ).to_dict()

        return object_info

    # 获取应用服务根据classes聚合统计的数量信息
    @classmethod
    def group_by_classes(cls, db: Session):
        object_info = db.query(cls).filter(
            cls.state
        ).with_entities(
            cls.classes,
            func.count(cls.name).label('server_count')
        ).group_by(cls.classes).to_dict()

        return object_info

    # 根据部门聚合，获取每个部门容器服务cpu的总数
    @classmethod
    def get_container_cpu_by_department(cls, db: Session):
        object_info = db.query(cls).filter(
            cls.state,
            cls.classes.in_(["k8s_deployment", "k8s_statefulset"])
        ).with_entities(
            cls.department,
            func.sum(cls.cpu_limit * cls.number).label('cpu_total')
        ).group_by(cls.department).to_dict()

        return object_info
